/*************************************************************************
	> File Name: text_query.cc
	> Author: likang
	> Mail:  
	> Created Time: 2014年12月22日 星期一 12时22分51秒
 ************************************************************************/

#include<iostream>
#include"TextQuery.h"
#include<sstream>
#include<cstdlib>

using namespace std;

void TextQuery::store_file(ifstream &is) {
	string textline;
	while (getline(is, textline)) {
		lines_of_text.push_back(textline);
	}
}

void TextQuery::build_map() {
	for (line_no line_num = 0; line_num != lines_of_text.size(); ++line_num) {
		istringstream line(lines_of_text[line_num]);
		string word;
		while (line >> word) {
			word_map[word].insert(line_num);
		}
	}
}

set<TextQuery::line_no>
TextQuery::run_query(const string &query_word) const {
	map<string, set<line_no> >::const_iterator loc = word_map.find(query_word);
	if (loc != word_map.end()) {
		return loc->second;
	}
	else {
		return set<line_no>();
	}
}

string TextQuery::text_line(line_no line) const {
	if (line < lines_of_text.size()) {
		return lines_of_text[line];
	}
	//throw std::out_of_range("line number out of range!");
}

string make_plural(int size, const string &s1, const string &s2) {
	return (size == 1) ? s1 : s1 + s2;
}

void print_results(const set<TextQuery::line_no> &locs,const string &s,const TextQuery &tq) {
	typedef set<TextQuery::line_no> line_nums;
	line_nums::size_type size = locs.size();
	cout << "\n" << s << " occurs " << size << make_plural(size, "time", "s") << endl;

	line_nums::const_iterator it = locs.begin();
	while (it != locs.end()) {
		cout << "\t(line " << (*it) + 1 << ") " << tq.text_line(*it++) << endl;
	}
}

int main(int argc, char *argv[]) {
	ifstream infile;
	if (argc < 2 ) {
		cerr << "No input file" << endl;
		return EXIT_FAILURE;
	}
	infile.open(argv[1]);
	if (!infile) {
		cerr << "No input file" << endl;
		return EXIT_FAILURE;
	}
	TextQuery tq;
	tq.read_file(infile);
	while (true) {
		cout << "please enter word to look for, or q to quit: ";
		string s;
		cin >> s;
		if (!cin || s == "q") {
			break;
		}
		set<TextQuery::line_no> locs = tq.run_query(s);
		print_results(locs, s, tq);
	}
	return 0;
}


